﻿using System.Collections.Generic;
using System.Linq;
using KTOP.Core.Domain.Matrix;

namespace KTOP.Homeworks.Hw5.Logics.HamiltonianRoutes
{
    internal class HamiltonianRouteBuilder
    {
        private readonly RMatrix _rMatrix;

        private HamiltonianRouteType HamiltonianIteration(Stack<int> route,  int startModule, int module)
        {
            route.Push(module);

            if (route.Count == _rMatrix.Size)
                return _rMatrix[module, startModule] > 0
                           ? HamiltonianRouteType.Iteration
                           : HamiltonianRouteType.Way;

            for (var col = 0; col < _rMatrix.Size; col++)
                if (_rMatrix[module, col] > 0)
                {
                    if (route.Contains(col) || module == col)
                        continue;

                    var status = HamiltonianIteration(route, startModule, col);
                    if (status != HamiltonianRouteType.None)
                        return status;
                }

            route.Pop();
            return HamiltonianRouteType.None;
        }

        public HamiltonianRoute Build()
        {
            var route = new Stack<int>();
            var routeType = HamiltonianIteration(route, 0, 0);

            return new HamiltonianRoute(route.Reverse(), routeType);
        }

        public HamiltonianRouteBuilder(RMatrix rMatrix)
        {
            _rMatrix = rMatrix;
        }

        public static HamiltonianRoute Build(RMatrix rMatrix)
        {
            return (new HamiltonianRouteBuilder(rMatrix)).Build();
        }
    }
}
